package net.sf.nlp.segment;

import java.util.Iterator;
import java.util.List;

import net.sf.nlp.segment.util.StringUtility;

public class Adjustment 
{
	public static void recognizeNumDateTime(List<SegNode> path, List<AtomicWord> atomicWords)
	{
		StringBuffer sb = new StringBuffer();
		
		for (int i = 0; i < path.size(); i++)
		{
			SegNode segNode = path.get(i);
			
			if (segNode.isDeleted())
				continue;
			
			int num = isNumber(path, atomicWords, segNode, i);
			if (num == -1)
				continue;
			
			i = num;
				
			segNode.setPosType(PosType.NUM);
			
			sb.delete(0, sb.length());
			sb.append(segNode.getNodeWord());
			
			int j;
			for (j = i + 1; j < path.size(); j++)
			{
				SegNode appendSegNode = path.get(j);
				if (appendSegNode.isDeleted())
					continue;
				
				
				num = isNumber(path, atomicWords, sb.toString(), appendSegNode, j);
				if (num == -1)
					break;
				
				j = num;
				
				List<AtomicWord> mergedAtomicWords = atomicWords.subList(segNode.getStart(), appendSegNode.getEnd() + 1);
				segNode.setAtomicWords(mergedAtomicWords);
				appendSegNode.setDeleted(true);
				
				sb.append(appendSegNode.getNodeWord());
			}
			
			if (j >= path.size())
				break;
			
			SegNode nextSegNode = path.get(j);
			
			if (StringUtility.isDateTimeSuffixWord(nextSegNode.getNodeWord()))
			{
				List<AtomicWord> mergedAtomicWords = atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1);
				
				segNode.setPosType(PosType.TIME);
				segNode.setAtomicWords(mergedAtomicWords);
				nextSegNode.setDeleted(true);
			}
		}
		
		deleteSegNode(path);
	}
	
	private static int isNumber(List<SegNode> path, List<AtomicWord> atomicWords, SegNode segNode, int index)
	{
		if (StringUtility.isNumber(segNode.getNodeWord()))
			return index;
		
		if (index + 1 < path.size() && StringUtility.isPartNumber(segNode.getNodeWord()))
		{
			SegNode nextSegNode = path.get(index + 1);
			
			if (StringUtility.isNumber(segNode.getNodeWord() + nextSegNode.getNodeWord()))
			{
				List<AtomicWord> mergedAtomicWords = atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1);
				segNode.setAtomicWords(mergedAtomicWords);
				nextSegNode.setDeleted(true);
				
				return index + 1;
			}
		}
		
		return -1;
	}
	
	private static int isNumber(List<SegNode> path, List<AtomicWord> atomicWords, String prefix, SegNode segNode, int index)
	{
		String temp = prefix + segNode.getNodeWord();
		if (StringUtility.isNumber(temp))
			return index;
		
		if (index + 1 < path.size() && StringUtility.isPartNumber(temp))
		{
			SegNode nextSegNode = path.get(index + 1);
			
			if (StringUtility.isNumber(temp + nextSegNode.getNodeWord()))
			{
				List<AtomicWord> mergedAtomicWords = atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1);
				segNode.setAtomicWords(mergedAtomicWords);
				nextSegNode.setDeleted(true);
				
				return index + 1;
			}
		}
		
		return -1;
	}
	
	private static void deleteSegNode(List<SegNode> path)
	{
		Iterator<SegNode> it = path.iterator();
		
		while (it.hasNext())
		{
			SegNode segNode = it.next();
			if (segNode.isDeleted())
				it.remove();
		}
	}
	
	public static void recognizePersonName(List<SegNode> path, List<AtomicWord> atomicWords, Dictionary personDict, ContextStat personContextStat)
	{
		getBestPosFromUnknownDict(path, personDict, personContextStat);
		
		recognizePersonName(path, atomicWords);
	}
	
	public static void recognizeForeignPersonName(List<SegNode> path, List<AtomicWord> atomicWords, Dictionary foreignPersonDict, ContextStat foreignPersonContextStat)
	{
		getBestPosFromUnknownDict(path, foreignPersonDict, foreignPersonContextStat);
		
		recognizeForeignPersonName(path, atomicWords);
	}
	
	public static void recognizeForeignPersonName(List<SegNode> path, List<AtomicWord> atomicWords)
	{
		recognizeUnkownWord(path, atomicWords, PosType.NOUN_PERSON);
	}
	
	public static void recognizePlaceName(List<SegNode> path, List<AtomicWord> atomicWords, Dictionary placePersonDict, ContextStat placePersonContextStat)
	{
		getBestPosFromUnknownDict(path, placePersonDict, placePersonContextStat);
		
		recognizeUnkownWord(path, atomicWords, PosType.NOUN_SPACE);
	}
	
	public static void recognizeUnkownWord(List<SegNode> path, List<AtomicWord> atomicWords, PosType posType)
	{
		String srcWord = "";
		
		for (int start = 1, end = start; start < path.size(); start++) 
		{
			SegNode segNode = path.get(start);
			
			if (segNode.isDeleted())
				continue;
			
			srcWord = segNode.getNodeWord();
			
			if (segNode.getBestPos().getTag() == 1) 
			{
				for (end = start + 1; end < path.size(); end++) 
				{
					SegNode tempSegNode = path.get(end);
					long bestTag = tempSegNode.getBestPos().getTag();
					if (bestTag == -1)
						continue;
					else if (bestTag == 1 || bestTag == 3) 
					{
						if (end > start + 1)
							srcWord += tempSegNode.getNodeWord();
					} 
					else if (bestTag == 2)
						srcWord += tempSegNode.getNodeWord();
					else
						break;
				}
			} 
			else if (segNode.getBestPos().getTag() == 2) 
			{
				for (end = start + 1; end < path.size(); end++) 
				{
					SegNode tempSegNode = path.get(end);
					long bestTag = tempSegNode.getBestPos().getTag();
					if (bestTag == -1)
						continue;
					else if (bestTag == 3) 
					{
						if (end > start + 1)
							srcWord += tempSegNode.getNodeWord();
					} 
					else if (bestTag == 2)
						srcWord += tempSegNode.getNodeWord();
					else
						break;
				}
			}
			
			if (end > start) 
			{
				SegNode startNameNode = path.get(start);
		        SegNode endNameNode = path.get(end);
		        
		        List<AtomicWord> mergedAtomicWords = atomicWords.subList(startNameNode.getStart(), endNameNode.getEnd());
		        startNameNode.setPosType(posType);
	        	startNameNode.setAtomicWords(mergedAtomicWords);
		        
		        for (int i = start + 1; i < end; i++)
		        	 path.get(i).setDeleted(true);
			}
		}
		
		deleteSegNode(path);
	}
	
	private static void getBestPosFromUnknownDict(List<SegNode> path, Dictionary unknownDict, ContextStat unknownContextStat)
	{
		for (SegNode segNode : path)
		{
			List<Pos> posList = segNode.getPosList();
			posList.clear();
			
			String nodeWord = segNode.getAliasNodeWord();
			
			getPosFromUnknownDict(posList, nodeWord, unknownDict, unknownContextStat);
			getPosFromCoreDict(posList, nodeWord, segNode.getWordItems(), unknownContextStat);
			
			if (posList.size() == 0)
				guessPersonTag(segNode, unknownContextStat);
		}
		
		viterbi(path, unknownContextStat);
	}
	
	private static void getPosFromUnknownDict(List<Pos> posList, String nodeWord, Dictionary unknownDict, ContextStat unknownContextStat)
	{
		List<WordItem> wordItems = unknownDict.getWordItems(nodeWord);
		
		if (wordItems != null)
		{
			for (WordItem wordItem : wordItems)
			{
				long tag = wordItem.getHandle();
	            double freq = (double)(1 + wordItem.getFreq()) / (unknownContextStat.getFreq(tag) + wordItems.size() + 1);
	            freq = -Math.log(freq);
	            
	            posList.add(new Pos(tag, freq));
			}
		}
	}
	
	private static void getPosFromCoreDict(List<Pos> posList, String nodeWord, List<WordItem> wordItems, ContextStat contextStat)
	{
		if (StringUtility.SENTENCE_BEGIN.equals(nodeWord))
			posList.add(new Pos(100, 0));
		else if (StringUtility.SENTENCE_END.equals(nodeWord))
        	posList.add(new Pos(101, 0));
		else
		{
			int totalFreq = 0;
			
	        if (wordItems != null && wordItems.size() > 0) 
	        {
	        	for (WordItem wordItem : wordItems)
	        		totalFreq += wordItem.getFreq();
	
	        	double freq = (double)(1 + totalFreq) / (contextStat.getFreq(0) + wordItems.size());
	        	freq = -Math.log(freq);
	        	
	            posList.add(new Pos(0, freq));
	        }
		}
	}
	
	private static void viterbi(List<SegNode> path, ContextStat contextStat)
	{
		for (int i = 1; i < path.size(); i++)
		{
			List<Pos> posList = path.get(i).getPosList();
			List<Pos> prePosList = path.get(i - 1).getPosList();
			
			//System.out.println(path.get(i).getNodeWord());
			for (Pos pos : posList)
			{
				int minPrev = 0;
	            double minFreq = 1000;
	            
				for (int j = 0; j < prePosList.size(); j++)
				{
					Pos prevPos = prePosList.get(j);
					
					double freq = contextStat.getPossibility((int)prevPos.getTag(), (int)pos.getTag());
					freq = prevPos.getFreq() - Math.log(freq);
		            
					if (freq < minFreq) 
		            {
		            	minFreq = freq;
		                minPrev = j;
		            }
				}
				
				pos.setBestPrePos(prePosList.get(minPrev));
				pos.setFreq(pos.getFreq() + minFreq);
			}
		}
		
		getBestPath(path);
	}
	
	private static void getBestPath(List<SegNode> path)
	{
		SegNode lastSegNode = path.get(path.size() - 1);
		List<Pos> posList = lastSegNode.getPosList();
		Pos bestPos = posList.get(0);
		
		for (int i = 1; i < posList.size(); i++)
		{
			Pos pos = posList.get(i);
			if (bestPos.getFreq() > pos.getFreq())
			{
				bestPos = pos;
			}
		}
		
		for (int i = path.size() - 1; i >= 0; i--)
		{
			SegNode segNode = path.get(i);
			segNode.setBestPos(bestPos);
			
			bestPos = bestPos.getBestPrePos();
		}
	}
	
	private static void guessPersonTag(SegNode segNode, ContextStat personContextStat)
	{
		List<Pos> posList = segNode.getPosList();
		String nodeWord = segNode.getAliasNodeWord();
		
		double freq = 0;
		
		if (nodeWord.indexOf("××") != -1) 
		{
			freq = (double) 1 / (double) (personContextStat.getFreq(6) + 1);
			posList.add(new Pos(6, freq));
	    } 
		else 
	    {
			freq = (double) 1 / (double) (personContextStat.getFreq(0) + 1);
			posList.add(new Pos(0, freq));

			if (StringUtility.getLen(nodeWord) >= 4) 
			{
			    freq = (double) 1 / (double) (personContextStat.getFreq(0) + 1);
			    posList.add(new Pos(0, freq));
			    freq = (double) 1 / (double) (personContextStat.getFreq(11) * 8);
			    posList.add(new Pos(11, freq));
			    freq = (double) 1 / (double) (personContextStat.getFreq(12) * 8);
			    posList.add(new Pos(12, freq));
			    freq = (double) 1 / (double) (personContextStat.getFreq(13) * 8);
			    posList.add(new Pos(13, freq));
			} 
			else if (StringUtility.getLen(nodeWord) == 2) 
			{
			    freq = (double) 1 / (double) (personContextStat.getFreq(0) + 1);
			    posList.add(new Pos(0, freq));
			    
			    AtomicWord atomicWord = segNode.getAtomicWords().get(0);
			    if (atomicWord.isChinese()) 
			    {
				    freq = (double) 1 / (double) (personContextStat.getFreq(1) + 1);
				    posList.add(new Pos(1, freq));
				    freq = (double) 1 / (double) (personContextStat.getFreq(2) + 1);
				    posList.add(new Pos(2, freq));
				    freq = (double) 1 / (double) (personContextStat.getFreq(3) + 1);
				    posList.add(new Pos(3, freq));
				    freq = (double) 1 / (double) (personContextStat.getFreq(4) + 1);
				    posList.add(new Pos(4, freq));
			    }
			    
				freq = (double) 1 / (double) (personContextStat.getFreq(11) * 8);
				posList.add(new Pos(11, freq));
				freq = (double) 1 / (double) (personContextStat.getFreq(12) * 8);
				posList.add(new Pos(12, freq));
				freq = (double) 1 / (double) (personContextStat.getFreq(13) * 8);
				posList.add(new Pos(13, freq));
			}
	    }
	}
	
	/**
	 * 人名模式匹配
	 * 
	 * <pre>
	 * 
	 *          BBCD 343 0.003606 
	 *          BBC 2 0.000021 
	 *          BBE 125 0.001314 
	 *          BBZ 30 0.000315 
	 *          BCD 62460 0.656624 
	 *          BEE 0 0.000000 
	 *          BE 13899 0.146116 
	 *          BG 869 0.009136 
	 *          BXD 4 0.000042 
	 *          BZ 3707 0.038971 
	 *          CD 8596 0.090367 
	 *          EE 26 0.000273 
	 *          FB 871 0.009157 
	 *          Y 3265 0.034324
	 *          XD 926 0.009735
	 *          
	 *          The person recognition patterns set
	 *          BBCD:姓+姓+名1+名2;
	 *          BBE: 姓+姓+单名;
	 *          BBZ: 姓+姓+双名成词;
	 *          BCD: 姓+名1+名2;
	 *          BE: 姓+单名;
	 *          BEE: 姓+单名+单名;韩磊磊
	 *          BG: 姓+后缀
	 *          BXD: 姓+姓双名首字成词+双名末字
	 *          BZ: 姓+双名成词;
	 *          B: 姓
	 *          CD: 名1+名2;
	 *          EE: 单名+单名;
	 *          FB: 前缀+姓
	 *          XD: 姓双名首字成词+双名末字
	 *          Y: 姓单名成词
	 * </pre>
	 */
	private static void recognizePersonName(List<SegNode> path, List<AtomicWord> atomicWords) 
	{
		// 人名识别模式
		final String[] patterns = { "BBCD", "BBC", "BBE", "BBZ", "BCD", "BEE", "BE", "BG", "BXD", "BZ",	"CDCD", "CD", "EE", "FB", "Y", "XD"};
		//final double[] factor = { 0.003606, 0.000021, 0.001314, 0.000315, 0.656624, 0.000021, 0.146116, 0.009136, 0.000042, 0.038971, 0, 0.090367, 0.000273, 0.009157, 0.034324, 0.009735, 0 };
		
		StringBuffer sb = new StringBuffer();
	  
		for (SegNode segNode : path)
			sb.append((char)('A' + segNode.getBestPos().getTag()));

		String sPos = sb.toString();
	  
		for (String pattern : patterns)
		{
			if ("CDCD".equals(pattern))
				continue;
	  
			int index = -1;
			while ((index = sPos.indexOf(pattern, index + 1)) != -1)
			{
				String beforeWord = path.get(index - 1).getNodeWord();
				String afterWord = path.get(index + pattern.length()).getNodeWord();
		  
				if ("·".equals(beforeWord) ||"·".equals(afterWord))
					continue;
	  
				String temp = sPos.substring(index + 2);
				if (temp.length() > 1)
					temp = temp.substring(0, 1);
				
				// Rule 1 for exclusion:前缀+姓+名1(名2): 规则(前缀+姓)失效；
				if ("FB".equals(pattern) && ("E".equals(temp) || "C".equals(temp) || "G".equals(temp))) 
					continue;
		          
				StringBuffer personName = new StringBuffer();
		          
		        for (int i = 0; i < pattern.length(); i++)
		        	personName.append(path.get(index + i).getNodeWord());
		        
		        SegNode startNameNode = path.get(index);
		        int endIndex = index + pattern.length();
		        SegNode endNameNode = path.get(index + pattern.length());
		        
		        List<AtomicWord> mergedAtomicWords = atomicWords.subList(startNameNode.getStart(), endNameNode.getStart());
		        startNameNode.setPosType(PosType.NOUN_PERSON);
	        	startNameNode.setAtomicWords(mergedAtomicWords);
		        
		        for (int i = index + 1; i < endIndex; i++)
		        	 path.get(i).setDeleted(true);
		        
		        //System.out.println(personName);
			}	      
		}
		
		deleteSegNode(path);
	}
	
	public static void recognizedLexical(List<SegNode> path, List<AtomicWord> atomicWords, ContextStat lexicalContextStat)
	{
		for (SegNode segNode : path)
		{
			List<Pos> posList = segNode.getPosList();
			posList.clear();
			
			if (segNode.getPosType() != null)
			{
				posList.add(new Pos(segNode.getPosType().getTag(), 0));
			}
			else
			{
				List<WordItem> wordItems = segNode.getWordItems();
				
				if (wordItems == null)
				{
					posList.add(new Pos(PosType.UNKNOWN.getTag(), 0));
				}
				else
				{
					for (WordItem wordItem : wordItems)
					{
						long tag = wordItem.getHandle();
						double value = -Math.log(1 + wordItem.getFreq());
		                value += Math.log(lexicalContextStat.getFreq(tag) + wordItems.size());
		                posList.add(new Pos(tag, value));
					}
				}
			}
		}
        
		viterbi(path, lexicalContextStat);
	}

	/**
	 * 对分词结果做最终的调整，主要是人名的拆分或重叠词的合并
	 * 
	 * @param optSegPath
	 * @param personTagger
	 * @param placeTagger
	 * @return
	 */
	public static void finaAdjust(List<SegNode> path, List<AtomicWord> atomicWords, Dictionary placeDict) 
	{
		
		for (int i = 0; i < path.size(); i++) 
		{
			SegNode segNode = path.get(i);
			
			if (segNode.isDeleted())
				continue;
			
			// Rule2 for overlap words ABB 一段段、一片片
			if (segNode.getBestPos().getTag() == PosType.NUM.getTag() && i + 2 < path.size() && 
				path.get(i + 1).isChineseWords(1) && path.get(i + 1).getNodeWord().equals(path.get(i + 2).getNodeWord())) 
			{
				segNode.setBestPos(new Pos(PosType.NUM.getTag(), 0));
				segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 2).getEnd() + 1));
				
				path.get(i + 1).setDeleted(true);
				path.get(i + 2).setDeleted(true);
				
				i += 2;
			}
			else if (segNode.getBestPos().getTag() == PosType.NUM.getTag() && i + 1 < path.size() && 
				path.get(i + 1).isChineseWords(2) && path.get(i + 1).getNodeWord().substring(0, 1).equals(path.get(i + 1).getNodeWord().substring(1, 2))) 
			{
				segNode.setBestPos(new Pos(PosType.NUM.getTag(), 0));
				segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 1).getEnd() + 1));
				
				path.get(i + 1).setDeleted(true);
				
				i += 1;
			}
			// Rule for words 跑一跑，动一动
			else if (segNode.isChineseWords(1) && i + 2 < path.size() && 
					"一".equals(path.get(i + 1).getNodeWord()) && segNode.getNodeWord().equals(path.get(i + 2).getNodeWord())) 
				{
					segNode.setBestPos(new Pos(PosType.VERB.getTag(), 0));
					segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 2).getEnd() + 1));
					
					path.get(i + 1).setDeleted(true);
					path.get(i + 2).setDeleted(true);
					
					i += 2;
				}
			// Rule3 for overlap words AA
			else if (segNode.isChineseWords(1) && i + 1 < path.size() && 
					segNode.getNodeWord().equals(path.get(i + 1).getNodeWord())) 
			{
				segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 1).getEnd() + 1));
				segNode.setBestPos(new Pos(PosType.ADJ.getTag(), 0));
				
				path.get(i + 1).setDeleted(true);
				
				if (segNode.getBestPos().getTag() == PosType.VERB.getTag() || path.get(i + 1).getBestPos().getTag() == PosType.VERB.getTag())// 30208='v'8256
					segNode.setBestPos(new Pos(PosType.VERB.getTag(), 0));

				if (segNode.getBestPos().getTag() == PosType.NOUN.getTag() || path.get(i + 1).getBestPos().getTag() == PosType.NOUN.getTag())// 30208='v'8256
					segNode.setBestPos(new Pos(PosType.NOUN.getTag(), 0));
				
				if (path.get(i + 2).isChineseWords(1)) 
				{// AAB:洗/洗/脸、蒙蒙亮
					if ((path.get(i + 1).getBestPos().getTag() == PosType.VERB.getTag() && path.get(i + 1).getBestPos().getTag() == PosType.NOUN.getTag()) ||
						(path.get(i + 1).getBestPos().getTag() == PosType.ADJ.getTag() && path.get(i + 1).getBestPos().getTag() == PosType.ADJ.getTag()))
					{
						segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 2).getEnd() + 1));
						path.get(i + 2).setDeleted(true);
						i += 1;
					}
				}
				
				i += 1;
			}
			// Rule 4: AAB 洗/洗澡
			else if (segNode.isChineseWords(1) && i + 1 < path.size() && 
					(segNode.getBestPos().getTag() == PosType.VERB.getTag() || segNode.getBestPos().getTag() == PosType.ADJ.getTag()) && 
					path.get(i + 1).isChineseWords(2) && path.get(i + 1).getNodeWord().indexOf(segNode.getNodeWord()) == 0) 
			{
				segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 1).getEnd() + 1));
				segNode.setBestPos(new Pos(PosType.ADJ.getTag(), 0));
				
				if (segNode.getBestPos().getTag() == PosType.VERB.getTag() || path.get(i + 1).getBestPos().getTag() == PosType.VERB.getTag())// 30208='v'8256
					segNode.setBestPos(new Pos(PosType.VERB.getTag(), 0));

				path.get(i + 1).setDeleted(true);
				
				i += 1;
			}
			// Rule 4: AAB 洗洗/澡
			else if (segNode.isChineseWords(2) && segNode.getNodeWord().substring(0, 1).equals(segNode.getNodeWord().substring(1, 2)) &&
					segNode.getBestPos().getTag() == PosType.VERB.getTag() && i + 1 < path.size() &&
					path.get(i + 1).isChineseWords(1) && path.get(i + 1).getBestPos().getTag() == PosType.NOUN.getTag()) 
			{
				segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 1).getEnd() + 1));
				segNode.setBestPos(new Pos(PosType.ADJ.getTag(), 0));
				
				if (segNode.getBestPos().getTag() == PosType.VERB.getTag() || path.get(i + 1).getBestPos().getTag() == PosType.VERB.getTag())// 30208='v'8256
					segNode.setBestPos(new Pos(PosType.VERB.getTag(), 0));

				path.get(i + 1).setDeleted(true);
				
				i += 1;
			}
			else if (segNode.getBestPos().getTag() / 256 == 'u' && segNode.getBestPos().getTag() % 256 != 0)// uj,ud,uv,uz,ul,ug->u
				segNode.setBestPos(new Pos('u' * 256,0));
			// AABB,朴朴素素
			else if (segNode.isChineseWords(1) && i + 2 < path.size() && path.get(i + 1).isChineseWords(2) &&
					path.get(i + 1).getNodeWord().indexOf(segNode.getNodeWord()) == 0 && path.get(i + 1).getNodeWord().indexOf(path.get(i + 2).getNodeWord()) == 1) 
			{
				segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 2).getEnd() + 1));
				segNode.setBestPos(path.get(i + 1).getBestPos());
				
				path.get(i + 1).setDeleted(true);
				path.get(i + 2).setDeleted(true);
				
				i += 2;
			}
			// 28275=='n'*256+'s' 地名+X
			else if (segNode.getBestPos().getTag() == PosType.NOUN_SPACE.getTag() && i + 1 < path.size())// PostFix
			{
				SegNode nextSegNode = path.get(i + 1);
				if (placeDict.getWordItems(nextSegNode.getNodeWord()) != null) 
				{
					segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1));
					segNode.setBestPos(new Pos(PosType.NOUN_SPACE.getTag(), 0));

					nextSegNode.setDeleted(true);
					
					i += 1;
				} 
				else if ("队".equals(nextSegNode.getNodeWord())) 
				{
					segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1));
					segNode.setBestPos(new Pos(PosType.NOUN_ORG.getTag(), 0));
					
					nextSegNode.setDeleted(true);
					
					i += 1;
				}
				else if (nextSegNode.isChineseWords(1) && "语文字杯".indexOf(nextSegNode.getNodeWord()) != -1) 
				{
					segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1));
					segNode.setBestPos(new Pos(PosType.NOUN_ZHUAN.getTag(), 0));
				
					nextSegNode.setDeleted(true);
					
					i += 1;
				} 
				else if ("裔".equals(nextSegNode.getNodeWord())) 
				{
					segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1));
					segNode.setBestPos(new Pos(PosType.NOUN.getTag(), 0));
					
					nextSegNode.setDeleted(true);
					
					i += 1;
				}
			} 
			else if (segNode.getBestPos().getTag() == PosType.VERB.getTag() || segNode.getBestPos().getTag() == PosType.VERB_NOUN.getTag() ||
					segNode.getBestPos().getTag() == PosType.NOUN.getTag())// v
			{
				if (i + 1 < path.size() && "员".equals(path.get(i + 1).getNodeWord())) 
				{
					segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), path.get(i + 1).getEnd() + 1));
					segNode.setBestPos(new Pos(PosType.NOUN.getTag(), 0));
					
					path.get(i + 1).setDeleted(true);
					
					i += 1;
				}
			}
			// www/nx ./w sina/nx;
			// ＥＩＭ/nx -６０１/m
			// ＳＨＭ/nx －/w １０１/m
			// 28280=='n'*256+'r'
			// 27904=='m'*256
			else if (segNode.getBestPos().getTag() == PosType.NOUN_LETTER.getTag() && i + 1 < path.size()) 
			{
				while (i + 1 < path.size()) 
				{
					SegNode nextSegNode = path.get(i + 1);
					if (nextSegNode.getBestPos().getTag() == PosType.NOUN_LETTER.getTag() || ".．-－".indexOf(nextSegNode.getNodeWord()) != -1 || 
						(nextSegNode.getBestPos().getTag() == PosType.NUM.getTag() && StringUtility.isNumber(nextSegNode.getNodeWord())))
					{
						segNode.setAtomicWords(atomicWords.subList(segNode.getStart(), nextSegNode.getEnd() + 1));
						
						nextSegNode.setDeleted(true);
						i++;
					} else
						break;
				}
			}
		}
		
		deleteSegNode(path);		
	}
}
